package com.cyzy.service.impl;
import com.cyzy.config.AiServiceConfig;
import com.cyzy.dto.AiResult;
import com.cyzy.dto.AiResultUsage;
import com.cyzy.dto.ContentDto;
import com.cyzy.service.AiService;
import com.cyzy.sse.EventSource;
import com.cyzy.sse.EventSourceListener;
import com.cyzy.sse.RealEventSource;
import com.cyzy.utils.JsonUtils;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.http.HttpHeaders;

import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@Service
public class AiServiceImpl implements AiService {
    private static final Logger logger = LoggerFactory.getLogger(AiServiceImpl.class);
    private static final String DONE = "[DONE]";
    private static final String OUT_OF_SCOPE_MESSAGE = "很抱歉，这个问题超出了我的知识范围。我只能回答与智慧农业系统相关的问题。";

    @Autowired
    private AiServiceConfig config;

    @Override
    public void streamChat(String content, HttpServletResponse response) throws IOException, InterruptedException {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Connection", "keep-alive");
        
        try (PrintWriter pw = response.getWriter()) {
            // 检查问题是否在智慧农业范围内
            if (!isAgricultureRelated(content)) {
                // 如果不在范围内，返回固定回复
                pw.write("data:" + JsonUtils.convertObj2Json(new ContentDto(OUT_OF_SCOPE_MESSAGE)) + "\n\n");
                pw.write("data:end\n\n");
                pw.flush();
                return;
            }
            
            streamAiResult(pw, content);
            pw.write("data:end\n\n");
            pw.flush();
        }
    }

    @Override
    public Map<String, Object> chat(String content) {
        // 检查问题是否在智慧农业范围内
        if (!isAgricultureRelated(content)) {
            // 如果不在范围内，返回固定回复
            Map<String, Object> response = new HashMap<>();
            Map<String, Object> message = new HashMap<>();
            message.put("role", "assistant");
            message.put("content", OUT_OF_SCOPE_MESSAGE);
            
            List<Map<String, Object>> choices = new ArrayList<>();
            Map<String, Object> choice = new HashMap<>();
            choice.put("message", message);
            choice.put("index", 0);
            choices.add(choice);
            
            response.put("choices", choices);
            return response;
        }
        
        Map<String, Object> params = buildAiRequestParams(content, false);
        String jsonParams = JsonUtils.convertObj2Json(params);
        
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + config.getApiKey());
        
        Request.Builder builder = new Request.Builder()
                .url(config.getChatCompletionsUrl())
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer " + config.getApiKey());
        
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request request = builder.post(body).build();
        
        OkHttpClient client = buildOkHttpClient();
                
        try {
            Response response = client.newCall(request).execute();
            String responseBody = response.body().string();
            
            if (!response.isSuccessful()) {
                logger.error("AI接口调用失败: {}", responseBody);
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("error", "AI接口调用失败");
                errorResult.put("statusCode", response.code());
                errorResult.put("response", responseBody);
                return errorResult;
            }
            
            return JsonUtils.convertJson2Obj(responseBody, Map.class);
        } catch (IOException e) {
            logger.error("调用AI接口异常: ", e);
            throw new RuntimeException("调用AI接口失败", e);
        }
    }

    /**
     * 检查问题是否与智慧农业相关
     * @param content 用户问题
     * @return 是否与智慧农业相关
     */
    private boolean isAgricultureRelated(String content) {
        if (content == null || content.trim().isEmpty()) {
            return false;
        }
        
        // 计算匹配的关键词数量
        int matchCount = 0;
        for (String keyword : config.getAgricultureKeywords()) {
            if (content.contains(keyword)) {
                matchCount++;
                // 如果达到阈值，立即返回true
                if (matchCount >= config.getKeywordMatchThreshold()) {
                    return true;
                }
            }
        }
        
        return false;
    }

    private void streamAiResult(PrintWriter pw, String content) throws InterruptedException {
        Map<String, Object> params = buildAiRequestParams(content, true);
        String jsonParams = JsonUtils.convertObj2Json(params);

        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + config.getApiKey());
        
        Request.Builder builder = new Request.Builder()
                .url(config.getChatCompletionsUrl())
                .addHeader("Accept", "text/event-stream")
                .addHeader("Authorization", "Bearer " + config.getApiKey());
                
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request request = builder.post(body).build();
        OkHttpClient client = buildOkHttpClient();

        // 计数器闩锁用于等待事件源处理完成
        CountDownLatch eventLatch = new CountDownLatch(1);

        RealEventSource realEventSource = new RealEventSource(request, new EventSourceListener() {
            @Override
            public void onEvent(EventSource eventSource, String id, String type, String data) {
                if (DONE.equals(data)) {
                    return;
                }
                String content = extractContent(data);
                if (content != null && !content.isEmpty()) {
                    pw.write("data:" + JsonUtils.convertObj2Json(new ContentDto(content)) + "\n\n");
                    pw.flush();
                }
            }

            @Override
            public void onClosed(EventSource eventSource) {
                super.onClosed(eventSource);
                eventLatch.countDown();
            }

            @Override
            public void onFailure(EventSource eventSource, Throwable t, Response response) {
                logger.error("调用接口失败", t);
                if (response != null) {
                    try {
                        logger.error("错误响应: {}", response.body().string());
                    } catch (IOException e) {
                        logger.error("读取错误响应异常", e);
                    }
                }
                eventLatch.countDown();
            }
        });
        
        // 建立连接
        realEventSource.connect(client);
        // 等待事件源处理完成
        eventLatch.await();
    }

    private OkHttpClient buildOkHttpClient() {
        return new OkHttpClient.Builder()
                .connectTimeout(config.getConnectTimeoutSeconds(), TimeUnit.SECONDS)
                .writeTimeout(config.getWriteTimeoutSeconds(), TimeUnit.SECONDS)
                .readTimeout(config.getReadTimeoutSeconds(), TimeUnit.SECONDS)
                .build();
    }

    private Map<String, Object> buildAiRequestParams(String content, boolean stream) {
        Map<String, Object> params = new HashMap<>();
        params.put("model", config.getModel());
        
        if (config.getMaxTokens() > 0) {
            params.put("max_tokens", config.getMaxTokens());
        }
        
        params.put("temperature", config.getTemperature());

        // 添加系统提示词
        Map<String, String> systemMessage = new HashMap<>();
        systemMessage.put("role", "system");
        systemMessage.put("content", config.getSystemPrompt());
        
        Map<String, String> userMessage = new HashMap<>();
        userMessage.put("role", "user");
        userMessage.put("content", content);

        List<Map> messages = new ArrayList<>();
        messages.add(systemMessage); // 首先添加系统提示词
        messages.add(userMessage);   // 然后添加用户消息
        
        params.put("messages", messages);
        params.put("stream", stream);
        
        return params;
    }

    private String extractContent(String data) {
        try {
            AiResult aiResult = JsonUtils.convertJson2Obj(data, AiResult.class);
            if (aiResult.getChoices() != null && !aiResult.getChoices().isEmpty() && 
                aiResult.getChoices().get(0).getDelta() != null) {
                return aiResult.getChoices().get(0).getDelta().getContent();
            }
            return "";
        } catch (Exception e) {
            logger.error("解析AI响应内容失败: {}", data, e);
            return "";
        }
    }
}